package edu.jxufe.nb112.blog.core.persist.service.user;

import edu.jxufe.nb112.common.code.exception.ExceptionCodeConstant;
import edu.jxufe.nb112.blog.core.persist.entity.SysConfig;
import edu.jxufe.nb112.blog.core.persist.mapper.sys.SysConfigMapper;
import edu.jxufe.nb112.common.code.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;

/**
 * Created by lvxi on 2017/11/18.
 * Note:
 */
@Service
public class SysConfigServiceImpl implements SysConfigService {

    private static final Logger LOG = LoggerFactory.getLogger(SysConfigServiceImpl.class.getName());

    @Autowired
    SysConfigMapper sysConfigMapper;

    /**
     * 加载系统模块配置
     * @return
     */
    @Cacheable(value = "configCache",key = "'sysCfgList'")
    @Transactional(readOnly = true)
    public List<SysConfig> loadSystemModuleConfig() {
        HashMap params = new HashMap();
        params.put("module","system");
        params.put("enable",true);
        List<SysConfig> ret = sysConfigMapper.listSysConfig(params);
        return ret;
    }

    @Cacheable(value = "configCache",key = "'sysCfg_'+#module+'_'+#keyName")
    @Transactional(readOnly = true)
    public SysConfig getSysConfig(String module,String keyName){
        HashMap params = new HashMap();
        params.put("module",module);
        params.put("keyName",keyName);
        params.put("enable",true);
        List<SysConfig> ret = sysConfigMapper.listSysConfig(params);
        if(ret.isEmpty()) {
            return null;
        }
        return ret.get(0);
}

    public Object newInstanceSysConfigValue(SysConfig sysConfig){
        try {
            if(null==sysConfig.getDataType()){
                sysConfig.setDataType("java.lang.String");
            }
            Class clazz = Class.forName(sysConfig.getDataType());
            Constructor constructor = clazz.getConstructor(String.class);
            Object value = constructor.newInstance(sysConfig.getKeyValue());
            return value;
        } catch (ClassNotFoundException e) {
            LOG.trace("读取模块{}配置{}错误,类型{}未找到",sysConfig.getModule(),sysConfig.getKeyName(),sysConfig.getDataType(),e);
            throw new ServiceException(e,ExceptionCodeConstant.SYS_CONFIG);
        } catch (NoSuchMethodException e) {
            LOG.trace("读取模块{}配置{}错误,类型{}未提供String.class参数构造方法",sysConfig.getModule(),sysConfig.getKeyName(),sysConfig.getDataType(),e);
            throw new ServiceException(e,ExceptionCodeConstant.SYS_CONFIG);
        } catch (IllegalAccessException e) {
            LOG.trace("读取模块{}配置{}错误,类型{}未提供可访问的String.class参数构造方法",sysConfig.getModule(),sysConfig.getKeyName(),sysConfig.getDataType(),e);
            throw new ServiceException(e,ExceptionCodeConstant.SYS_CONFIG);
        } catch (InstantiationException e) {
            LOG.trace("读取模块{}配置{}错误,类型{}实例化失败",sysConfig.getModule(),sysConfig.getKeyName(),sysConfig.getDataType(),e);
            throw new ServiceException(e,ExceptionCodeConstant.SYS_CONFIG);
        } catch (InvocationTargetException e) {
            LOG.trace("读取模块{}配置{}错误,类型{}实例化抛出异常",sysConfig.getModule(),sysConfig.getKeyName(),sysConfig.getDataType(),e);
            throw new ServiceException(e,ExceptionCodeConstant.SYS_CONFIG);
        }
    }
}
